package com.tools.ad;

import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Message;
import android.text.format.DateUtils;
import android.view.View;
import android.view.ViewGroup;

import com.cpu.time.AppRunTimeConfig;
import com.daps.weather.notification.DapWeatherNotification;
import com.hm.ads.sdk.HmAdsInitListener;
import com.hm.ads.sdk.HmAdsSDK;
import com.hm.ads.sdk.HmAdsSDKConfig;
import com.hm.adsbuisiness.AdsContants;
import com.hm.adsbuisiness.bean.dapweather.HmWeatherAdPlace;
import com.hm.adsbuisiness.bean.daswipe.HmSwipeAdPlace;
import com.hm.adsbuisiness.service.AdActionException;
import com.hm.base.android.mob.AMApplication;
import com.hm.base.android.mob.AModule;
import com.hm.base.android.mob.task.AServiceWraper;
import com.hm.base.android.mob.task.ATaskMarkPool;
import com.swipe.SwipeMgr;
import com.swipe.i.w;
import com.swipe.ui.ao;
import com.tools.ad.bean.AppInfo;
import com.tools.ad.manager.ADBeanManager;
import com.tools.ad.manager.AdSceneManager;
import com.tools.ad.receiver.EngineerBroadcastReceiver;
import com.tools.ad.store.ADSharedPrefManager;
import com.tools.ad.strategy.ADStrategyManager;
import com.tools.ad.strategy.outer.SwipeExecutor;
import com.tools.ad.util.GARecordUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import lab.galaxy.yahfa.HookMain;

import static com.tools.ad.ADConstant.PROTOCOL_TYPE.INVISIBLE_TYPE;


/**
 * desc:
 * date: 2017/12/19 15:34
 * author: ancun
 */
public class ADModule extends AModule implements HmAdsInitListener {

    /**
     * 必须与 app module 的 xml（modules）文件中的 key 保持一致
     */
    public static final String MODULE_KEY = "ad_module";

    private ADBeanManager mADBeanManager;

    private boolean isHmSDKInit;
    private long lastPrepareTime;

    public ADModule(AMApplication context, String moduleMark) {
        super(context, moduleMark);
        isHmSDKInit = false;
    }

    @Override
    public void initForLoginOut() {

    }

    @Override
    public void initForLongLive() {
        EntranceType[] entranceTypes = EntranceType.values();
        for (EntranceType entranceType : entranceTypes) {
            if (entranceType != EntranceType.UNKNOWN) {
                try {
                    entranceType.getAdScene().release();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    protected void doInitContext() throws Exception {
    }

    @Override
    protected void doBuildModule() throws Exception {
        mADBeanManager = new ADBeanManager(imContext, this);
    }

    @Override
    protected void doInitModule() throws Exception {
        initHmAdSDK();
        initEtapSdk();
        registerScreenBroadcast();
        AppRunTimeConfig.init(imContext);
    }

    private void initHook() {
        Method hook = null;
        Method backup = null;
        Class obj_class = null;
        try {
            if (isUserBatmobi()) {
                //快划视图重载
                Class[] pareTyple5 = {Object.class};
                obj_class = Class.forName("com.tools.ad.manager.InnerHookManager");
                hook = obj_class.getMethod("swipeSlideReloadHook", pareTyple5);

                obj_class = Class.forName("com.swipe.ui.SlideMenuView");
                HookMain.findAndBackupAndHook(obj_class, "a", "()V", hook, backup);

                //快划item视图适配器getview
                Class[] pareTyple6 = {Object.class, Integer.TYPE, View.class, ViewGroup.class};
                obj_class = Class.forName("com.tools.ad.manager.InnerHookManager");
                hook = obj_class.getMethod("swipeItemgetViewHook", pareTyple6);

                obj_class = Class.forName("com.swipe.b.d");
                HookMain.findAndBackupAndHook(obj_class, "getView", "(ILandroid/view/View;Landroid/view/ViewGroup;)Landroid/view/View;", hook, backup);
            }

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT != Build.VERSION_CODES.O_MR1) {

                if (BuildConfig.DEBUG) {
                    Field a = com.swipe.i.v.class.getDeclaredField("a");
                    a.setAccessible(true);
                    a.set(null, true);
                }

                //hook滑动事件一
                Class[] pareTyple = {Object.class};
                obj_class = Class.forName("com.tools.ad.manager.InnerHookManager");
                hook = obj_class.getMethod("swipeTriggerViewHook", pareTyple);

                obj_class = Class.forName("com.swipe.ui.aq");
                HookMain.findAndBackupAndHook(obj_class, "a", "()Landroid/view/WindowManager$LayoutParams;", hook, backup);

                //hook滑动事件二
                Class[] pareTyple1 = {Object.class};
                obj_class = Class.forName("com.tools.ad.manager.InnerHookManager");
                hook = obj_class.getMethod("swipeTriggerLayoutHook", pareTyple1);

                obj_class = Class.forName("com.swipe.e");
                HookMain.findAndBackupAndHook(obj_class, "n", "()V", hook, backup);
            }

            //快划hook
            Class[] pareTyple = {Object.class, ao.class};
            obj_class = Class.forName("com.tools.ad.manager.InnerHookManager");
            hook = obj_class.getMethod("swipeShowHook", pareTyple);

            obj_class = Class.forName("com.swipe.SwipeMgr");
            HookMain.findAndBackupAndHook(obj_class, "a", "(Lcom/swipe/ui/ao;)V", hook, backup);

            //swipe广告加载hook
            Class[] pareTyple2 = {Object.class};
            obj_class = Class.forName("com.tools.ad.manager.InnerHookManager");
            hook = obj_class.getMethod("swipeLoadAdHook", pareTyple2);

            obj_class = Class.forName("com.swipe.e");
            HookMain.findAndBackupAndHook(obj_class, "j", "()V", hook, backup);

            //天气hook
            Class[] pareTyple3 = {Context.class, String.class};
            obj_class = Class.forName("com.tools.ad.manager.InnerHookManager");
            hook = obj_class.getMethod("WeatherUrlJump", pareTyple3);

            obj_class = Class.forName("com.daps.weather.base.e");
            HookMain.findAndBackupAndHook(obj_class, "b", "(Landroid/content/Context;Ljava/lang/String;)V", hook, backup);

            //天气广告加载hook
            Class[] pareTyple4 = {Object.class};
            obj_class = Class.forName("com.tools.ad.manager.InnerHookManager");
            hook = obj_class.getMethod("weatherLoadAdHook", pareTyple4);

            obj_class = Class.forName("com.daps.weather.DapWeatherActivity");
            HookMain.findAndBackupAndHook(obj_class, "d", "()V", hook, backup);

            //天气日志hook，用于判断天气界面关闭
            Class[] pareType5 = {String.class, String.class};
            obj_class = Class.forName("com.tools.ad.manager.InnerHookManager");
            hook = obj_class.getMethod("weatherLogHook", pareType5);

            obj_class = Class.forName("com.daps.weather.base.d");
            HookMain.findAndBackupAndHook(obj_class, "a", "(Ljava/lang/String;Ljava/lang/String;)V", hook, backup);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void initHmAdSDK() {
        HmAdsSDKConfig config = new HmAdsSDKConfig();
        config.setAdMobKey(ADConstant.ADMOB_APP_KEY);
        config.setUseCloudConfig(true);
        config.setUseKeepLive(true);
        config.setLoadTrueUser(true);
        config.setReInstallCheck(true);
        config.setHostUrl(ADConstant.AD_CONFIG_URL);
        config.setAppId(BuildConfig.APP_ID);
        config.setMopubKey(ADConstant.MOPUB_KEY);

        if (BuildConfig.PROTOCOL_TYPE == INVISIBLE_TYPE) {
            config.setIsAppIdProtocol(true);
        }
        HmAdsSDK.getInstance().init(imContext, config, this);
    }

    private void registerScreenBroadcast() {
        final IntentFilter filter1 = new IntentFilter();
        filter1.addAction(Intent.ACTION_SCREEN_OFF);
        filter1.addAction(Intent.ACTION_SCREEN_ON);
        filter1.addAction(Intent.ACTION_USER_PRESENT);
        filter1.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        imContext.registerReceiver(new EngineerBroadcastReceiver(), filter1);

        final IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_PACKAGE_ADDED);
        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
        filter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
        //filter.addAction(Intent.ACTION_PACKAGE_FIRST_LAUNCH);
        filter.setPriority(2147483647);
        filter.addDataScheme("package");
        imContext.registerReceiver(new EngineerBroadcastReceiver(), filter);
    }


    @Override
    public String TAG() {
        return ADConstant.TAG;
    }

    @Override
    public ATaskMarkPool getTaskMarkPool() {
        return getADBeanManager().getADTaskMarkPool();
    }

    @Override
    public AServiceWraper getServiceWraper() {
        return getADBeanManager().getADServiceWrapper();
    }

    public ADBeanManager getADBeanManager() {
        return mADBeanManager;
    }

    public ADSharedPrefManager getADSharedPrefManager() {
        return getADBeanManager().getADSharedPrefManager();
    }

    public ADStrategyManager getADStrategyManager() {
        return getADBeanManager().getADStrategyManager();
    }

    /**
     * 广告加载管理
     *
     * @return
     */
    public AdSceneManager getAdSceneManager() {
        return getADBeanManager().getAdSceneManager();
    }

    @Override
    protected void subHandleMessage(Message msg) {
        if (msg.what == R.id.msg_ad_engine_outer_ad) {
            //SDK如果初始化完成就直接开始应用外广告
            if (isHmSDKInit()) {
                loadOuterAD(msg);
            } else {
                Message message = Message.obtain();
                message.what = R.id.msg_ad_prepare_outer_ad;
                message.obj = msg.obj;
                sendMessageDelayed(message, 1500);
            }

        } else if (msg.what == R.id.msg_ad_prepare_outer_ad) {
            loadOuterAD(msg);
        } else if (msg.what == R.id.msg_receive_swipe_close) {
            //快划菜单关闭，延迟五秒加载广告
            handleMobEmptyDelayMessage(R.id.msg_need_load_ad_swipe_close, 5000);
        } else if (msg.what == R.id.msg_weather_close_hook) {
            //天气界面关闭，延迟五秒加载广告
            handleMobEmptyDelayMessage(R.id.msg_need_load_ad_weather_close, 5000);
        } else if (msg.what == R.id.msg_need_load_ad_swipe_close) {
            loadSwipeCloseAD();
        } else if (msg.what == R.id.msg_need_load_ad_weather_close) {
            loadWeatherCloseAD();
        }
    }

    private void loadSwipeCloseAD() {
        getAdSceneManager().load(EntranceType.SWIPE_CLOSE);
    }

    private void loadWeatherCloseAD() {
        getAdSceneManager().load(EntranceType.WEATHER_CLOSE);
    }


    private void loadOuterAD(Message msg) {
        //过滤一秒内的多次触发点
        if (System.currentTimeMillis() - lastPrepareTime < DateUtils.SECOND_IN_MILLIS) {
            return;
        }
        lastPrepareTime = System.currentTimeMillis();

        boolean loadRealProtect = false;
        boolean loadFullScreen = false;
        boolean loadSwipeGuide = false;
        String action = "";

        if (msg.obj instanceof String) {
            action = (String) msg.obj;

        }
        //触发实时自动清理弹窗广告
        if (Intent.ACTION_USER_PRESENT.equals(action) && getADSharedPrefManager().getAutoCleanAdEnable()) {
            loadRealProtect = getAdSceneManager().load(EntranceType.AUTO_CLEAN);
        }

        //触发应用外广告,过来应用的安装和卸载
        if (!loadRealProtect && !(msg.obj instanceof AppInfo)
                && getADSharedPrefManager().getAppOuterAdEnable()) {

            loadFullScreen = getAdSceneManager().load(EntranceType.APP_OUTER_AD);
        }

        try {
            if (Intent.ACTION_USER_PRESENT.equals(action)//用户解锁
                    && SwipeMgr.getInstance().isSwipeEnable()//是否可以快滑
                    && getADSharedPrefManager().getSwipeAdEnable() // 用户是否打开快滑设置
                    ) {

                HmSwipeAdPlace swipeAdPlace = HmAdsSDK.getInstance().getDuSwipeAdPlace();
                SwipeExecutor executor = (SwipeExecutor) getADStrategyManager().getExecutorByEntranceType(EntranceType.SWIPE);
                if (swipeAdPlace != null && executor.isOutProtect(swipeAdPlace)) {
                    w.a().c(false);
                    swipeAdPlace.setSwipeOpen(true);
                }

                if (!loadRealProtect && !loadFullScreen) {
                    loadSwipeGuide = getAdSceneManager().load(EntranceType.SWIPE);
                }

                if (!loadRealProtect && !loadFullScreen && !loadSwipeGuide) {
                    getAdSceneManager().load(EntranceType.WEATHER);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 触发应用安装与卸载广告
        if (msg.obj instanceof AppInfo) {
            Message message = Message.obtain();
            message.what = R.id.msg_ad_smart_monitor_app_info;
            message.obj = msg.obj;
            imContext.handleMobMessage(message);
        }
    }

    @Override
    public void onHmAdsInitComplete() {
        AMApplication.getInstance().handleMobEmptyMessage(R.id.msg_ad_sdk_init_finish);
        final HmSwipeAdPlace swipeAdPlace = HmAdsSDK.getInstance().getDuSwipeAdPlace();
        SwipeExecutor executor = (SwipeExecutor) getADStrategyManager().getExecutorByEntranceType(EntranceType.SWIPE);
        if (swipeAdPlace != null && executor.isOutProtect(HmAdsSDK.getInstance().getDuSwipeAdPlace())) {
            try {
                if (SwipeMgr.getInstance().isSwipeEnable() && getADSharedPrefManager().getSwipeAdEnable()) {
                    w.a().c(false);
                    swipeAdPlace.setSwipeOpen(true);
                }
            } catch (AdActionException e) {
                //            e.printStackTrace();
            }
        }

        HmWeatherAdPlace weatherAdPlace = HmAdsSDK.getInstance().getDuWeatherAdPlace();
        if (weatherAdPlace != null) {
            DapWeatherNotification notification = DapWeatherNotification.getInstance(imContext);
            notification.setOngoing(false);
            notification.setNotificationClickListener(new DapWeatherNotification.WeatherNotificationListener() {
                @Override
                public void onClick(int i) {
                    String label = "";
                    switch (i) {
                        case 1:
                            label = ADGAConstant.FUNC_CLICK_NOTI_TODAY_WEATHER;
                            break;
                        case 2:
                            label = ADGAConstant.FUNC_CLICK_NOTI_TEMP_WEATHER;
                            break;
                        case 3:
                            label = ADGAConstant.FUNC_CLICK_NOTI_NEXT_WEATHER;
                            break;
                        default:
                            label = String.valueOf(i);
                            break;
                    }
                    GARecordUtils.report(imContext, ADGAConstant.C_FUNC, ADGAConstant.A_CLICK, label);
                }

                @Override
                public void onShow(int i) {
                    String label = "";
                    switch (i) {
                        case 1:
                            label = ADGAConstant.FUNC_SHOW_NOTI_TODAY_WEATHER;
                            break;
                        case 2:
                            label = ADGAConstant.FUNC_SHOW_NOTI_TEMP_WEATHER;
                            break;
                        case 3:
                            label = ADGAConstant.FUNC_SHOW_NOTI_NEXT_WEATHER;
                            break;
                        default:
                            label = String.valueOf(i);
                            break;
                    }
                    GARecordUtils.report(imContext, ADGAConstant.C_FUNC, ADGAConstant.A_SHOW, label);

                }
            });
        }

        isHmSDKInit = true;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {
            initHook();
        }
    }

    @Override
    public void onHmAdsUpdate() {

    }

    /**
     * Organic : 自然流量用户
     * Other ： 应用识别不到的渠道 都归为 Other 用户
     * 一般情况下：因为 Other 为不明渠道用户，广告策略 及 功能行为 与 organic 保持一致
     *
     * @return
     */
    public boolean isOrganicOrOtherChannel() {
        return AdsContants.ORGANIC_CHANNEL.equals(HmAdsSDK.getInstance().getReferrerChannel())
                || AdsContants.OTHER_CHANNEL.equals(HmAdsSDK.getInstance().getReferrerChannel());
    }

    public boolean isHmSDKInit() {
        return isHmSDKInit;
    }

    private boolean isUserBatmobi() {
        return false;
    }

    private void initEtapSdk() {
        if (isUserBatmobi()) {
            //nothing todo
        }
    }


}
